﻿namespace Pibby.Core.Feeds
{
	using System;
	using System.Linq;
	using System.Xml;
	using System.Xml.Linq;

	public class AtomFeedReader
	{
		#region Xml Constants

		const string FeedNode = "feed";
		const string ChannelNode = "channel";
		const string TitleNode = "title";
		const string LinkNode = "link";
		const string SubTitleNode = "subtitle";
		const string CopyrightNode = "copyright";
		const string UpdatedNode = "updated";
		const string ImageNode = "image";
		const string ItunesImageNode = "itunes:image";
		const string EntryNode = "entry";
		const string UrlNode = "url";
		const string HrefAttr = "href";
		const string VersionAttr = "version";
		
		#endregion

		public Feed Read(XmlReader xmlReader)
		{
			/*XDocument doc = XDocument.Load(reader);
			
			var entries = from item in doc.Root.Elements().Where(i => i.Name.LocalName == "entry")
						  select new Item
						  {
							  //FeedType = FeedType.Atom,
							  Description = item.Elements().First(i => i.Name.LocalName == "content").Value,
							  Link = item.Elements().First(i => (i.Name.LocalName == "link") && (i.Attribute("enclosure") != null)).Attribute("href").Value,
							  PublicationDate = ParseDate(item.Elements().First(i => i.Name.LocalName == "published").Value),
							  Title = item.Elements().First(i => i.Name.LocalName == "title").Value
						  };


			var feed = new Feed(entries.ToList());

			// plug in extra details here...

			return feed;
			 */

			if (xmlReader == null)
				throw new ArgumentNullException("xmlDoc", Resources.Rss_NullObjectError);

			var atom = new Feed();

			xmlReader.Read();

			if (xmlReader.NodeType == XmlNodeType.XmlDeclaration)
			{
				xmlReader.Read();
			}

			if (!xmlReader.Name.Equals(FeedNode, StringComparison.CurrentCultureIgnoreCase))
			{
				throw new FeedReadException("This is not an atom feed");
			}

			bool complete = false;

			while (!complete && xmlReader.Read())
			{
				string nodeName = xmlReader.Name.ToLower();

				switch (xmlReader.NodeType)
				{
					case XmlNodeType.Element:

						switch (nodeName)
						{
							case TitleNode:

								xmlReader.Read();
								atom.Title = xmlReader.Value;
								break;

							case LinkNode:

								xmlReader.Read();

								try
								{
									// need to find the link with the value enclosure...
									atom.Link = Web.UriBuilder.Create(xmlReader.Value);
								}
								catch (UriFormatException)
								{
									// swallow it
								}

								break;

							case SubTitleNode:

								xmlReader.Read();
								atom.Description = XmlSanitizer.StripHtml(xmlReader.Value);
								break;

							case UpdatedNode:

								xmlReader.Read();
								atom.PublicationDate = new PublicationDate(xmlReader.Value).Date;
								break;

							case EntryNode:
								{
									Item newItem = Item.Create(xmlReader);

									if (newItem.Enclosure != null && newItem.Enclosure.Url != null)
									{
										atom.Items.Add(newItem);
									}

								}
								break;
						}
						break;

					case XmlNodeType.EndElement:

						complete = nodeName.Equals(ChannelNode, StringComparison.CurrentCultureIgnoreCase)
							|| nodeName.Equals(FeedNode, StringComparison.CurrentCultureIgnoreCase);
						break;
				}
			}

			// if pubdate is still null
			// look for most recent pub date 
			// in list of items...

			if (atom.PublicationDate == null || atom.PublicationDate == DateTime.MinValue)
			{
				atom.PublicationDate = atom.Items.MostRecentDate;
			}

			return atom;

		}

		private DateTime ParseDate(string date)
		{
			DateTime result;

			if (DateTime.TryParse(date, out result))
				return result;
			else
				return DateTime.MinValue;
		}
	}
}
